﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Storm.TextEditor.Interacting
{
    /// <summary>
    /// Represents a helper class for the WeakTimer class.
    /// </summary>
    public class WeakTimerHelper
    {
        #region Fields

        public const int Speed = 10;

        private static Timer timer = GetTimer();
        private static ArrayList listeners = new ArrayList();

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the Timer of the WeakTimerHelper.
        /// </summary>
        public Timer Timer
        {
            get { return timer; }
            set { timer = value; }
        }

        #endregion

        #region Methods

        #region Public

        /// <summary>
        /// Attaches the given WeakTimer to the WeakTimerHelper.
        /// </summary>
        /// <param name="t">Timer to attach.</param>
        public static void Attach(WeakTimer t)
        {
            WeakReference reference = new WeakReference(t);
            listeners.Add(reference);
        }

        /// <summary>
        /// Detaches the given WeakTimer from the WeakTimerHelper.
        /// </summary>
        /// <param name="t">Timer to detach.</param>
        public static void Detach(WeakTimer t)
        {
            List<WeakReference> removeReferences = new List<WeakReference>();
            foreach (WeakReference reference in listeners)
            {
                try
                {
                    if (reference.Target == t)
                        removeReferences.Add(reference);
                }
                catch
                {
                }
            }

            removeReferences.ForEach(listeners.Remove);
        }

        #endregion

        #region Private

        /// <summary>
        /// Initializes a new timer and returns it.
        /// </summary>
        /// <returns>The newly initialized timer.</returns>
        private static Timer GetTimer()
        {
            Timer t = new Timer();

            t.Interval = Speed;
            t.Tick += DoTick;
            t.Enabled = true;

            return t;
        }

        /// <summary>
        /// Loops through all WeakReferences in the WeakTimerHelper's listeners and calls the WeakTimers' DoTick method.
        /// </summary>
        /// <param name="s">Sender object.</param>
        /// <param name="e">EventArgs.</param>
        private static void DoTick(object s, EventArgs e)
        {
            foreach (WeakReference reference in listeners)
            {
                if (reference.IsAlive == true)
                {
                    try
                    {
                        (reference.Target as WeakTimer).DoTick(null, EventArgs.Empty);
                    }
                    catch
                    {
                    }
                }
            }
        }

        #endregion

        #endregion

        /// <summary>
        /// Initializes a new instance of WeakTimerHelper.
        /// </summary>
        public WeakTimerHelper()
        {
        }
    }
}
